package cn.com.netedge.iot.common.utils;

import cn.com.netedge.iot.common.constants.CacheKeyConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.*;

@Configuration
@RefreshScope
public class FrontEndUtil {
    private static final Logger logger = LoggerFactory.getLogger(FrontEndUtil.class);

    @Value("${frontEnd.networkIpPrefix}")
    private String networkIpPrefix;
    public static String NETWORK_IP_PREFIX;

    @PostConstruct
    public void init() {
        NETWORK_IP_PREFIX = networkIpPrefix;
    }
    public static long getMachineNo() {
        try {
            // 获取所有网络接口的枚举
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

            // 遍历所有网络接口
            while (interfaces.hasMoreElements()) {
                NetworkInterface networkInterface = interfaces.nextElement();
                // 获取该网络接口下的所有IP地址
                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    InetAddress address = addresses.nextElement();
                    String ip = address.getHostAddress();
                    if(ip.startsWith(NETWORK_IP_PREFIX)) {
                        String[] ipArray = ip.split("\\.");
                        if(ipArray.length == 4) {
                            return Integer.parseInt(ipArray[3]);
                        }
                    }
                }
            }
        } catch (SocketException e) {
            // 处理网络接口获取异常
            logger.info("无法获取网络接口信息: {}", e.getMessage());
        }
        Long no = RedisUtil.incr(CacheKeyConstants.KEY_GLOABL_MACHINE_NO);
        if(no == null) {
            no = -1L;
        }
        return no;
    }

    /**
     * 判断自己是否为领导，最小序号节点名与机器名是否相同
     *
     * @return
     */
    public static boolean isLeader(String appName, String machineName, int heartBeatInterval) {
        Set<String> machineNameList = RedisUtil.hkeys(appName);
        if (machineNameList == null || machineNameList.isEmpty()) {
            logger.info("{} 's name list is empty.", appName);
            return false;
        }
        List<String> children = new ArrayList<>(machineNameList.size());
        Date now = new Date();
        Date compareTime = DateUtil.addSeconds(now, -(heartBeatInterval * 3));
        String value;
        Date hearBeatTime;
        for (String item : machineNameList) {
            value = RedisUtil.hget(appName, item);
            if (StringUtil.isEmpty(value)) {
                logger.info("machine:{} 's heartbeat time is null.", item);
                continue;
            }
            hearBeatTime = DateUtil.LongStrToDate(value);
            if (hearBeatTime == null) {
                logger.info("value:{} can't convert date.", value);
                continue;
            }
            if (hearBeatTime.after(compareTime)) { //离线
                logger.info("machine:{} --> online.", item);
                children.add(item);
                continue;
            }
            RedisUtil.hdel(appName, item);
        }
        if(children.size() > 0) {
            Collections.sort(children);
            String leader = children.get(0);
            if (!machineName.equals(leader)) {
                return false;
            }
        }
        return true;
    }
}